// PersistentSortVisitor.h: interface for the PersistentSortVisitor class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_PERSISTENTSORTVISITOR_H__3C3762AB_A39D_428B_9FC5_C6A87B8B611F__INCLUDED_)
#define AFX_PERSISTENTSORTVISITOR_H__3C3762AB_A39D_428B_9FC5_C6A87B8B611F__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "PersistentObjectVisitor.h"
#include "PersistentSaveDelete.h"
#include "PersistentModify.h"
#include "PersistentCreateDelete.h"
#include "PersistentCreate.h"
#include "Part.h"
#include "Volume.h"
#include "SupportHanger.h"
#include "Joint.h"


class PersistentObject;
namespace PersistentObjectOperation
{
	template
		<
		typename _PersistentSaveDelete,
		typename _PersistentModify,
		typename _PersistentCreateDelete,
		typename _PersistentCreate
		>
		class DllExport PersistentSortVisitorInterface : public PersistentObjectVisitor,
														 public VolumeVisitor,
														 public PartVisitor,
														 public JointVisitor,
														 public SHVisitor
	{
		UE_TEMPLATE_DECLARE_DYNAMIC(PersistentSortVisitorInterface);
public:
	PersistentSortVisitorInterface(){}
	virtual ~PersistentSortVisitorInterface(){}
	
public:
	BOOL Visit(Volume*& pVolume)
	{
		ASSERT(pVolume);
		BOOL bResult = FALSE;
		PersistentObjectVisitor* pVisitor = GetVisit(pVolume);
		if(pVisitor != NULL)
		{
			void* p = pVisitor->QueryInterface(VolumeVisitor::RuntimeClass());
			if(p != NULL)
				return ((VolumeVisitor*)(p))->Visit(pVolume);
		}
		return TRUE;
	}
	
	BOOL Visit(Part*& pPart)
	{
		ASSERT(pPart);
		PersistentObjectVisitor* pVisitor = GetVisit(pPart);
		if(pVisitor != NULL)
		{
			void* p = pVisitor->QueryInterface(PartVisitor::RuntimeClass());
			if(p != NULL)
				return ((PartVisitor*)(p))->Visit(pPart);
		}
		return TRUE;
	}
	
	BOOL Visit(SupportHanger*& pSH)
	{
		ASSERT(pSH);
		PersistentObjectVisitor* pVisitor = GetVisit(pSH);
		if(pVisitor != NULL)
		{
			void* p = pVisitor->QueryInterface(SHVisitor::RuntimeClass());
			if(p != NULL)
				return ((SHVisitor*)(p))->Visit(pSH);
		}
		return TRUE;
	}
	
	BOOL Visit(Joint*& pJoint)
	{
		ASSERT(pJoint);
		PersistentObjectVisitor* pVisitor = GetVisit(pJoint);
		if(pVisitor != NULL)
		{
			void* p = pVisitor->QueryInterface(JointVisitor::RuntimeClass());
			if(p != NULL)
				return ((JointVisitor*)(p))->Visit(pJoint);
		}
		return TRUE;
	}
	
	void StartPersistent(){
		m_SaveDelete.StartPersistent();
		m_Modify.StartPersistent();
		m_Create.StartPersistent();
	}

	void EndPersistent(){
		m_SaveDelete.EndPersistent();
		m_Modify.EndPersistent();
		m_Create.EndPersistent();
	}

private:
	PersistentObjectVisitor* GetVisit(PersistentObject* pObject)
	{
		ASSERT(pObject);
		
		if(pObject->IsCreateState())
		{
			return &m_Create;
		}
		else if(pObject->IsModifyState())
		{
			return &m_Modify;
		}
		else if(pObject->IsSaveDeleteState())
		{
			return &m_SaveDelete;
		}
		else
		{
			return NULL;
		}
		
	}
	
private:
	_PersistentSaveDelete m_SaveDelete;
	_PersistentModify m_Modify;
	_PersistentCreateDelete m_CreateDelete;
	_PersistentCreate m_Create;
	};

#define Temp_Pre \
	template <typename _PersistentSaveDelete, typename _PersistentModify, \
	typename _PersistentCreateDelete,	typename _PersistentCreate>

#define Class_Suf <_PersistentSaveDelete, _PersistentModify, _PersistentCreateDelete, _PersistentCreate>

#define ClassName PersistentSortVisitorInterface<_PersistentSaveDelete, _PersistentModify, _PersistentCreateDelete, _PersistentCreate>

	UE_TEMPLATE_IMPLEMENT_MULTI_INHERIT_DYNAMIC(Temp_Pre, Class_Suf, PersistentSortVisitorInterface)
		UE_IMPLEMENT_PARENT_DYNAMIC(ClassName, PersistentObjectVisitor)
		UE_IMPLEMENT_PARENT_DYNAMIC(ClassName, VolumeVisitor)
		UE_IMPLEMENT_PARENT_DYNAMIC(ClassName, PartVisitor)
		UE_IMPLEMENT_PARENT_DYNAMIC(ClassName, JointVisitor)
		UE_IMPLEMENT_PARENT_DYNAMIC(ClassName, SHVisitor)
	UE_IMPLEMENT_MULTI_INHERIT_END()
#undef ClassName

	typedef PersistentSortVisitorInterface<PersistentSaveDelete,
		PersistentModify, PersistentCreateDelete, PersistentCreateBatch> PersistentSortVisitor;
}
#endif // !defined(AFX_PERSISTENTSORTVISITOR_H__3C3762AB_A39D_428B_9FC5_C6A87B8B611F__INCLUDED_)
